﻿using System;
using System.Linq.Expressions;
using System.Reflection;

namespace MetroIoc
{
    public class ContainerConfiguration : IConfiguration
    {
        private readonly IContainer _container;

        public ContainerConfiguration(IContainer container)
        {
            if (container == null)
                throw new ArgumentNullException("container");

            _container = container;
        }

        public IConfiguration Configure<T>(InjectedMemberBase injection)
        {
            var fullName = injection.DeriveFullName<T>();
            _container.RegisterInstance(injection.MemberValue.GetType(), injection.MemberValue, fullName);
            return this;
        }

        public IConfiguration Property<T, TProp>(Expression<Func<T, TProp>> propertyExpression, TProp value)
        {
            var memberExpression = propertyExpression.Body as MemberExpression;
            if (memberExpression == null)
                throw new ArgumentException("propertyExpression is not a valid member expression");

            var propertyInfo = memberExpression.Member as PropertyInfo;
            if (propertyInfo == null)
                throw new ArgumentException("propertyExpression does not represent a valid property");

            return Configure<T>(new InjectedProperty<TProp>(propertyInfo.Name, value));
        }

        public IConfiguration ConstructorParam<T, TParam>(string name, TParam value)
        {
            return Configure<T>(new InjectedConstructorParam<TParam>(name, value));
        }
    }
}
